class EventEmitter {
    constructor() {
        // 事件对象，存放订阅的类型和回调事件
        this.events = {};
    }

    // on方法用于订阅事件，接收事件名称和回调函数作为参数
    on(eventName, callback) {
        // 不存在则创建一个新列表存储，注意数据：一个名字可以订阅多个事件函数
        if (!this.events[eventName]) {
            this.events[eventName] = [];
        }
        this.events[eventName].push(callback);
    }

     // off方法用于取消订阅事件，可根据事件名称和具体的回调函数来取消指定的订阅
    off(eventName, callback) {
        if (this.events[eventName]) {
            const offCallbackIndex = this.events[eventName].indexOf(callback);
            if(offCallbackIndex !== -1)  this.events[eventName].splice(offCallbackIndex, 1);
            // this.events[eventName] = this.events[eventName].filter(fn => {
            //     // 使用过滤器filter 如果fn和传入的callback相等的时候就删除它
            //     fn != callback;
            // });
            if(this.events[eventName].length === 0) {
                delete this.events[eventName];
            }
        }
    }

    // emit方法用于触发事件，接收事件名称以及可选的参数，会依次执行该事件对应的所有回调函数
    emit(eventName, ...args) {
        this.events[eventName]
            && this.events[eventName].forEach(callback => {
                callback(...args)
            });
    }

    // once方法用于订阅只执行一次的事件，内部借助on方法和一个标记函数来实现
    once(eventName, callback) {
        let onlyOnce = function (...args) {
            //执行此回调函数
            callback(...args);
            //执行完毕后关闭回调函数，就达到了一次性触发
            this.off(eventName, onlyOnce);
        }
        //绑定onlyOnce回调函数
        this.on(eventName, callback);
    }
}

// let em = new EventEmitter();

// function workDay() {
//     console.log("每天工作");
// }
// function makeMoney() {
//     console.log("赚100万");
// }
// function sayLove() {
//     console.log("向喜欢的人示爱");
// }

// em.on("money", workDay);
// em.on("money", makeMoney);
// em.on("love", sayLove);
// em.on("work", workDay);

// em.emit("money");
// em.emit("love");
// em.emit("work");

// 使用示例
const eventEmitter = new EventEmitter();

// 订阅事件 'event1'
const callback1 = (data) => {
    console.log('事件1触发，收到数据:', data);
};
eventEmitter.on('event1', callback1);

// 订阅只执行一次的事件 'event2'
const callback2 = (data) => {
    console.log('一次性事件2触发，收到数据:', data);
};
eventEmitter.once('event2', callback2);

// 触发 'event1' 事件
eventEmitter.emit('event1', '来自事件1的消息');
// 再次触发 'event1' 事件，依然会执行对应的回调函数
eventEmitter.emit('event1', '又一次来自事件1的消息');

// 触发 'event2' 事件，只会执行一次对应的回调函数
eventEmitter.emit('event2', '来自一次性事件2的消息');
// 再次触发 'event2' 事件，由于已经取消订阅，不会执行回调函数了

// 取消订阅 'event1' 中的 callback1
eventEmitter.off('event1', callback1);
// 再次触发 'event1' 事件，因为已经取消订阅，所以不会执行任何回调函数了
eventEmitter.emit('event1', '这是取消订阅后触发的消息');
